package com.yupi.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.mapper.DepartmentMapper;
import com.yupi.springbootinit.mapper.WorkflowTaskMapper;
import com.yupi.springbootinit.model.dto.production.ProductionTaskClaimRequest;
import com.yupi.springbootinit.model.dto.production.ProductionTaskCompleteRequest;
import com.yupi.springbootinit.model.dto.production.ProductionTaskStartRequest;
import com.yupi.springbootinit.model.dto.production.printingrecord.*;
import com.yupi.springbootinit.model.entity.Department;
import com.yupi.springbootinit.model.entity.WorkflowTask;
import com.yupi.springbootinit.model.vo.WorkflowTaskVO;
import com.yupi.springbootinit.model.vo.production.*;
import com.yupi.springbootinit.service.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 生产执行服务实现（主服务 - 协调者）
 */
@Slf4j
@Service
public class ProductionExecutionServiceImpl implements ProductionExecutionService {

    // ==================== 依赖注入 ====================

    @Resource
    private WorkflowTaskMapper workflowTaskMapper;
    @Resource
    private DepartmentMapper departmentMapper;

    @Resource
    private WorkflowTaskService workflowTaskService;

    // ==================== 子服务依赖 ====================

    @Resource
    private ProductionCleaningService productionCleaningService;

    @Resource
    private ProductionProcessService productionProcessService;

    @Resource
    private ProductionStatisticsService productionStatisticsService;

    @Resource
    private ProductionProgressService productionProgressService;

    @Resource
    private ProductionTaskQueryService productionTaskQueryService;

    // ==================== 任务查询（委托给 ProductionTaskQueryService）====================

    @Override
    public Page<WorkflowTaskVO> pageAvailableTasks(Long userId, String status, long current, long size) {
        return productionTaskQueryService.pageAvailableTasks(userId, status, current, size);
    }

    @Override
    public Page<WorkflowTaskVO> pageMyProductionTasks(Long userId, String status, long current, long size) {
        return productionTaskQueryService.pageMyProductionTasks(userId, status, current, size);
    }

    @Override
    public Page<WorkflowTaskVO> pageCleaningTasks(Long userId, String status, long current, long size) {
        return productionTaskQueryService.pageCleaningTasks(userId, status, current, size);
    }

    @Override
    public Page<WorkflowTaskVO> pageProductionTasks(Long userId, String status, long current, long size) {
        return productionTaskQueryService.pageProductionTasks(userId, status, current, size);
    }

    @Override
    public WorkflowTaskVO getTaskDetail(Long taskId) {
        return productionTaskQueryService.getTaskDetail(taskId);
    }

    @Override
    public PmcSetupVO getPmcSetup(Long taskId) {
        return productionTaskQueryService.getPmcSetup(taskId);
    }

    // ==================== 统计查询（委托给 ProductionStatisticsService）====================

    @Override
    public Map<String, Long> getTaskStatistics(Long userId) {
        return productionStatisticsService.getTaskStatistics(userId);
    }

    @Override
    public Map<String, Long> getCleaningTaskStatistics(Long userId) {
        return productionStatisticsService.getCleaningTaskStatistics(userId);
    }

    @Override
    public Map<String, Long> getProductionTaskStatistics(Long userId) {
        return productionStatisticsService.getProductionTaskStatistics(userId);
    }

    // ==================== 进度查询（委托给 ProductionProgressService）====================

    @Override
    public ProductionProgressVO getTaskProgress(Long taskId) {
        return productionProgressService.getTaskProgress(taskId);
    }

    @Override
    public Map<Long, ProductionProgressVO> batchGetTaskProgress(List<Long> taskIds) {
        return productionProgressService.batchGetTaskProgress(taskIds);
    }

    @Override
    public void attachProgressSummary(List<WorkflowTaskVO> vos) {
        productionProgressService.attachProgressSummary(vos);
    }

    // ==================== 任务操作（保留在主服务）====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean claimTask(ProductionTaskClaimRequest request, Long userId, String userName, Long departmentId) {
        if (request == null || request.getTaskId() == null || userId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数不合法");
        }
        boolean success = workflowTaskService.claimTask(request.getTaskId(), userId, userName, departmentId);
        if (success) {
            log.info("生产任务认领成功: taskId={}, userId={}, userName={}",
                    request.getTaskId(), userId, userName);
        }
        return success;
    }

    @Override
    public void checkOperationPermission(WorkflowTask task, Long operatorId, String operatorName) {
        if (task == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "任务不存在");
        }

        Department dept = departmentMapper.selectById(task.getDepartmentId());
        if (dept == null) {
            log.warn("任务关联的部门不存在: taskId={}, departmentId={}",
                    task.getId(), task.getDepartmentId());
            // 部门不存在时，默认需要认领（安全策略）
            if (task.getClaimedBy() == null) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "请先认领任务");
            }
            if (!task.getClaimedBy().equals(operatorId)) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "只能操作自己认领的任务");
            }
            return;
        }

        // 获取部门配置（null 或 1 都表示需要认领）
        Integer requireClaim = dept.getRequireTaskClaim();
        boolean needClaim = (requireClaim == null || requireClaim == 1);

        if (needClaim) {
            // 需要认领的部门（PMC、品质等）
            if (task.getClaimedBy() == null) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "请先认领任务");
            }
            if (!task.getClaimedBy().equals(operatorId)) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "只能操作自己认领的任务");
            }
            log.debug("权限检查通过（需认领部门）: taskId={}, operatorId={}, claimedBy={}",
                    task.getId(), operatorId, task.getClaimedBy());
        } else {
            // 不需要认领的部门（生产部 SC001）
            if (task.getClaimedBy() == null) {
                // 首次操作时，自动记录操作员（软认领）
                LocalDateTime now = LocalDateTime.now();
                task.setClaimedBy(operatorId);
                task.setClaimedByName(operatorName);
                task.setClaimedTime(now);

                // 更新数据库
                UpdateWrapper<WorkflowTask> uw = new UpdateWrapper<>();
                uw.eq("id", task.getId())
                        .eq("isDelete", 0)
                        .isNull("claimedBy")
                        .set("claimedBy", operatorId)
                        .set("claimedByName", operatorName)
                        .set("claimedTime", now)
                        .set("updateTime", now);

                int rows = workflowTaskMapper.update(null, uw);
                if (rows > 0) {
                    log.info("生产部任务自动记录操作员（软认领）: taskId={}, operatorId={}, operatorName={}",
                            task.getId(), operatorId, operatorName);
                } else {
                    log.warn("自动认领失败（可能被其他用户抢先）: taskId={}, operatorId={}",
                            task.getId(), operatorId);
                }
            }
            log.debug("权限检查通过（免认领部门）: taskId={}, operatorId={}",
                    task.getId(), operatorId);
        }
    }

    // ==================== 清机流程（委托给 ProductionCleaningService）====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startPowderCleaning(StartCleaningRequest request, Long loginUserId, String loginUserName) {
        return productionCleaningService.startPowderCleaning(request, loginUserId, loginUserName);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completePowderCleaning(CompleteCleaningRequest request, Long loginUserId, String loginUserName) {
        return productionCleaningService.completePowderCleaning(request, loginUserId, loginUserName);
    }

    @Override
    public CleaningRecordVO getCleaningRecord(Long taskId) {
        return productionCleaningService.getCleaningRecord(taskId);
    }

    // ==================== 工序流程（委托给 ProductionProcessService）====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startProduction(StartProductionFlowRequest request, Long loginUserId, String loginUserName) {
        return productionProcessService.startProduction(request, loginUserId, loginUserName);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startProcess(StartProcessRequest request, Long loginUserId, String loginUserName) {
        return productionProcessService.startProcess(request, loginUserId, loginUserName);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ProcessCompleteVO completeProcess(CompleteProcessRequest request, Long loginUserId, String loginUserName) {
        return productionProcessService.completeProcess(request, loginUserId, loginUserName);
    }

    @Override
    public ProductionTaskDetailVO getProductionTaskDetail(Long taskId) {
        return productionProcessService.getProductionTaskDetail(taskId);
    }

    // ==================== 辅助接口 ====================

    @Override
    public List<OperatorVO> listOperators() {
        // TODO: 实现操作员列表查询
        return List.of();
    }

    // ==================== 废弃的遗留 API（保持兼容性）====================

    @Override
    @Deprecated
    public boolean startTask(ProductionTaskStartRequest request, Long userId, String userName) {
        log.warn("Deprecated API startTask invoked. Use startProduction/startProcess instead. " +
                        "reqTaskId={}, userId={}",
                request != null ? request.getTaskId() : null, userId);
        throw new BusinessException(ErrorCode.OPERATION_ERROR,
                "接口已废弃，请使用新流程接口（开始生产/开始工序）");
    }

    @Override
    @Deprecated
    public boolean completeTask(ProductionTaskCompleteRequest request, Long userId, String userName) {
        log.warn("Deprecated API completeTask invoked. Use completeProcess instead. " +
                        "reqTaskId={}, userId={}",
                request != null ? request.getTaskId() : null, userId);
        throw new BusinessException(ErrorCode.OPERATION_ERROR,
                "接口已废弃，请使用新流程接口（完成工序）");
    }
}